package com.lenovo.testreport.jenkins;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lenovo.testreport.jenkins.model.Job;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author CJF
 * @date 2018/12/7
 */
public class JenkinsApi {
    //jenkins登录账号
    public static String username = "lijie";
    //jenkins登录密码
    public static String password = "lenovo123456";
    //jenkins登录url
    public static String jenkinsUrl = "http://172.16.22.105/jenkins";

    public static String buildToken = "buildToken";

    public static void main(String[] args) throws ClientProtocolException, IOException {


        // String jobName = "PublicCloud_Language(Chinese)_Environment_Test_Gray";
        // boolean result = JenkinsApi.stopJob(jobName, false, "xxxx");
        List<Job> list = getJobList("QA");
        for (Job e : list
                ) {
            System.out.println(e);
        }
    }

    /**
     * 调用jenkins接口，构建job
     * 1、jobName:需要构建的jenkins工程的名字
     * 2、buildJobParams：构建jenkins工程时需要的参数
     * 3、isNeedParams：jenkins工程的类型，如果jenkins工程带参数，isNeedParams=ture(isNeedParams=true时，buildJobParams生效，参数格式：key1=value1&key2=value2...，不填写参数时jenkins使用默认参数)
     * 如果jenkins工程不带参数，isNeedParams=false(isNeedParams=false时，buildJobParams不生效，可以随便填写)
     * <p>
     * red 失败 blue 成功 aborted_anime 构建中
     **/
    public static boolean buildJob(String jobName, Boolean isNeedParams, String buildJobParams) throws IOException {
        //jenkins构建job的url
        String jenkinsBuildUrl = jenkinsUrl + "/job/" + jobName + "/build";
        if (isNeedParams == true) {
            jenkinsBuildUrl = jenkinsUrl + "/job/" + jobName + "/buildWithParameters" + "?" + buildJobParams;
        }
        URI uri = URI.create(jenkinsBuildUrl);
        HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(host, basicAuth);
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
        HttpPost httpPost = new HttpPost(uri);
        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache(authCache);
        HttpResponse response = httpClient.execute(host, httpPost, localContext);
        // EntityUtils.toString(response.getEntity());
        // System.out.println(response.getStatusLine().getStatusCode());
        int statusCode = response.getStatusLine().getStatusCode();

        if (statusCode == 201 || statusCode == 200) {
            return true;
        } else {
            return false;
        }
    }

    public static String getBuildStatus(String jobName) throws IOException {
        String jenkinsBuildUrl = jenkinsUrl + "/job/" + jobName + "/api/json?pretty=true&tree=color";
        //System.out.println(jenkinsBuildUrl);
        URI uri = URI.create(jenkinsBuildUrl);
        HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(host, basicAuth);
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
        HttpPost httpPost = new HttpPost(uri);
        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache(authCache);
        HttpResponse response = httpClient.execute(host, httpPost, localContext);

        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity()));
        String status = jsonObject.getString("color");

        String result = "无法获取状态";
        switch (status) {
            case "red":
                result = "构建失败！";
                break;
            case "blue":
                result = "构建成功！";
                break;
            case "aborted":
                result = "构建终止！";
                break;
            case "aborted_anime":
                result = "构建中!";
                break;
        }

        //  System.out.println(response.getEntity());
        // System.out.println(response.getStatusLine().getStatusCode());

        return result;
    }

    /**
     * 按类型获取JOB列表。 类型为JOB名称最后一个下划线后的字符串
     *
     * @param type
     * @return
     * @throws IOException
     */
    public static List<Job> getJobList(String type) throws IOException {
        boolean flag = false;

        if (type.contains("%")) {
            flag = true;
        }
        String jenkinsBuildUrl = jenkinsUrl + "/view/公有融合自动化测试/api/json?pretty=true&tree=jobs[*[*]]";
        URI uri = URI.create(jenkinsBuildUrl);
        HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(host, basicAuth);
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
        HttpPost httpPost = new HttpPost(uri);
        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache(authCache);
        HttpResponse response = httpClient.execute(host, httpPost, localContext);
        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity()));
        JSONArray jsonArray = jsonObject.getJSONArray("jobs");
        List<Job> list = new ArrayList<>();
        String[] strs = type.split("%");
        type = strs[0];
        for (int i = 0; i < jsonArray.size(); i++) {
            if (Filter().contains(jsonArray.getJSONObject(i).getString("name"))) {
                continue;
            }
            String tempname = jsonArray.getJSONObject(i).getString("name").toLowerCase();
            if (!tempname.endsWith(type.toLowerCase())) {
                continue;
            }
            if (flag == true) {

                if (!tempname.contains(strs[1].toLowerCase())) {
                    continue;
                }
            }
            list.add(toJob(jsonArray.getJSONObject(i)));
        }
        //br.close();
        return list;
    }

    /**
     * 转换为对应的JobModel类
     *
     * @param jsonObject
     * @return
     */
    private static Job toJob(JSONObject jsonObject) {
        String color = jsonObject.getString("color");
        String name = jsonObject.getString("name");
        String url = jsonObject.getString("url");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String lastBuildTime, lastSucBuildTime, lastFailBuildTime;
        try {
            Long lastBuild = Long.valueOf(jsonObject.getJSONObject("lastBuild").getString("timestamp"));
            lastBuildTime = sdf.format(new Date(lastBuild));
        } catch (Exception e) {
            lastBuildTime = "无构建记录";
        }
        try {
            Long lastSucBuild = Long.valueOf(jsonObject.getJSONObject("lastSuccessfulBuild").getString("timestamp"));
            lastSucBuildTime = sdf.format(lastSucBuild);
        } catch (Exception e) {
            lastSucBuildTime = "无成功记录";
        }
        try {
            Long lastFailBuild = Long.valueOf(jsonObject.getJSONObject("lastFailedBuild").getString("timestamp"));
            lastFailBuildTime = sdf.format(lastFailBuild);
        } catch (Exception e) {
            lastFailBuildTime = "无失败记录";
        }

        String lastResult = jsonObject.getJSONObject("lastBuild").getString("result");
        String detail = jsonObject.getString("description");
        String inQueue = jsonObject.getString("inQueue");

        return new Job(color, name, url, lastBuildTime, lastResult, lastSucBuildTime, lastFailBuildTime, detail, inQueue);
    }

    /**
     * 停止JOB
     *
     * @param jobName
     * @param isNeedParams
     * @param buildJobParams
     * @return
     * @throws IOException
     */
    public static boolean stopJob(String jobName, boolean isNeedParams, String buildJobParams) throws IOException {
        String jenkinsBuildUrl = jenkinsUrl + "/job/" + jobName + "/api/json?pretty=true";
        URI uri = URI.create(jenkinsBuildUrl);
        HttpHost host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(host, basicAuth);
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
        HttpPost httpPost = new HttpPost(uri);
        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache(authCache);
        HttpResponse response = httpClient.execute(host, httpPost, localContext);
        try {
            JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity()));
            String num = jsonObject.getJSONObject("lastBuild").getString("number");

            jenkinsBuildUrl = jenkinsUrl + "/job/" + jobName + "/" + num + "/stop";
            uri = URI.create(jenkinsBuildUrl);
            httpPost = new HttpPost(uri);
            response = httpClient.execute(host, httpPost, localContext);
            int statusCode = response.getStatusLine().getStatusCode();

        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * JOB过滤器，不想显示JOB添加到 Resouces下的Config中的文本中
     *
     * @return
     * @throws IOException
     */
    public static String Filter() throws IOException {

        File file = ResourceUtils.getFile("classpath:Config/JobFilter.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));
        StringBuilder sb = new StringBuilder();
        String temp;
        while ((temp = br.readLine()) != null) {
            sb.append(temp + "\n");
        }
        return sb.toString();
    }
}
